package com.young.ums.service.impl;

import com.young.common.exception.BaseException;
import com.young.common.util.CommonUtil;
import com.young.common.core.dal.service.IDataAccessService;
import com.young.common.util.Page;
import com.young.common.util.StringUtils;
import com.young.ums.core.ETopic;
import com.young.ums.core.PublishSubscribeCenter;
import com.young.ums.model.Navigate;
import com.young.ums.service.INavigateService;
import com.young.ums.util.UmsConstants;
import org.springframework.stereotype.Service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
* 导航资源服务实现
* Created by imrookie on 2018-10-8.
*/
@Service("navigateService")
public class NavigateServiceImpl implements INavigateService {

    @Resource(name = "dataAccessService")
    IDataAccessService dataAccessService;//数据层服务

    @Resource
    PublishSubscribeCenter publishSubscribeCenter;

    private static final Logger logger = LoggerFactory.getLogger(NavigateServiceImpl.class);

    private static final String MAPPER = "com.young.ums.mapper.navigate";//mapper的namespace

    //获取数据列表
    @Override
    public List<Navigate> getList(Navigate obj) {
        return dataAccessService.getList(MAPPER + ".getList", obj);
    }

    //获取数据列表(分页)
    @Override
    public List<Navigate> getPage(Navigate obj, Page page) {
        return dataAccessService.getList(MAPPER + ".getList", obj, page);
    }

    //查询单条
    @Override
    public Navigate get(String id) {
        return dataAccessService.getObject(MAPPER + ".get", id);
    }

    //统计数量
    @Override
    public int count(Navigate obj) {
        return dataAccessService.getObject(MAPPER + ".count", obj);
    }

    //修改
    @Override
    public int update(Navigate obj) {
        obj.setUpdateTime(new Date());

        boolean refresh = false;//刷新子节点标志
        if (StringUtils.isNotBlank(obj.getParentId())){
            //父节点发生变化则刷新子孙节点
            Navigate old = this.get(obj.getId());//老信息
            if (!StringUtils.equals(obj.getParentId(), old.getParentId())){
                if (UmsConstants.DEFAULT.ROOT_NAVIGATE.equals(obj.getParentId())){//ROOT虚拟节点在表中不存在,手动设置为1
                    obj.setNavLevel(1);//更新层级
                } else {
                    Navigate parent = this.get(obj.getParentId());
                    obj.setNavLevel(parent.getNavLevel() + 1);//更新层级
                }
                refresh = true;
            }
        }

        int i = dataAccessService.update(MAPPER + ".update", obj);
        if (refresh){
            refreshAllChildLevel(obj, 1);//刷新子孙节点的层级信息
        }
        return i;
    }

    /**
     * 刷新所有的子孙节点层级信息
     * @param parent
     */
    private void refreshAllChildLevel(Navigate parent, int count) {
        if (count > 10){
            logger.error("[刷新资源子孙节点层级信息] 子孙节点深度过大,请检查是否存在节点之间循环引用");
            throw new BaseException("节点可能存在循环引用");
        }
        Navigate navigate = new Navigate();
        navigate.setParentId(parent.getId());
        List<Navigate> childList = this.getList(navigate);
        if (childList != null && childList.size() > 0){
            for (Navigate n : childList){
                n.setNavLevel(parent.getNavLevel() + 1);//新的层级
                n.setUpdateTime(new Date());
                dataAccessService.update(MAPPER + ".update", n);
                refreshAllChildLevel(n, count + 1);//递归调用
            }
        }
    }

    //批量删除
    @Override
    public int delete(String[] idArr) {
        int i = 0;
        for(String id : idArr){
            i += this.delete(id);
        }
        return i;
    }

    //删除单条
    @Override
    public int delete(String id) {
        //判断是否存在子节点,存在子节点不允许删除
        Navigate navigate = new Navigate();
        navigate.setParentId(id);
        int childNum = this.count(navigate);
        if (childNum > 0){
            throw new BaseException("禁止删除存在子节点的资源");
        }
        //执行删除
        int i= dataAccessService.delete(MAPPER + ".delete", id);
        //向发布订阅中心发布删除消息
        publishSubscribeCenter.publish(ETopic.NAVIGATE_DEL, id);
        return i;
    }

    //插入
    @Override
    public int insert(Navigate obj) {
        if (StringUtils.isBlank(obj.getId())){
            obj.setId(CommonUtil.getUUID());
        }
        obj.setCreateTime(new Date());
        obj.setUpdateTime(new Date());
        obj.setTrashFlag(UmsConstants.TrashFlag.NO);
        if (StringUtils.isBlank(obj.getParentId())){//默认父节点为ROOT
            obj.setParentId(UmsConstants.DEFAULT.ROOT_NAVIGATE);
        }
        if (!UmsConstants.DEFAULT.ROOT_NAVIGATE.equals(obj.getParentId())){
            Navigate parent = this.get(obj.getParentId());//父节点
            if (parent != null){
                obj.setNavLevel(parent.getNavLevel() + 1);
            }
        }else {
            obj.setNavLevel(1);
        }
        return dataAccessService.insert(MAPPER + ".insert", obj);
    }

    //批量插入
    @Override
    public int batchInsert(List<Navigate> list) {
        int i = 0;
        for(Navigate item : list){
            i += this.insert(item);
        }
        return i;
    }

    /**
     * 判断uri资源是否存在
     *
     * @param uri uri
     * @return
     */
    @Override
    public boolean existTheUriNavigate(String uri) {
        Navigate navigate = new Navigate();
        navigate.setHref(uri);//uri
        navigate.setType(UmsConstants.NavigateType.URI);//uri资源
        navigate.setTrashFlag(UmsConstants.TrashFlag.NO);//未删除
        return this.count(navigate) > 0;
    }

}